package cn.snowsoft.iot.module.warning.service.warning.config;

import cn.snowsoft.iot.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.snowsoft.iot.framework.common.pojo.CommonResult;
import cn.snowsoft.iot.module.cps.api.equipment.AdminEquipmentApi;
import cn.snowsoft.iot.module.cps.api.equipment.dto.EquipmentDTO;
import cn.snowsoft.iot.module.job.api.XxljobAdminApi;
import cn.snowsoft.iot.module.warning.controller.admin.home.vo.EquipmentRelateWarningVO;
import cn.snowsoft.iot.module.warning.controller.admin.home.vo.WarningConfigStatusVO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.config.vo.WarningDetailVO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.config.vo.WarningPageVO;
import cn.snowsoft.iot.module.warning.controller.admin.warning.config.vo.WarningSaveVO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.config.ConfigActionDO;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.config.ConfigRule;
import cn.snowsoft.iot.module.warning.dal.dataobject.warning.config.WarningDO;
import cn.snowsoft.iot.module.warning.dal.mysql.warning.config.WarningMapper;
import cn.snowsoft.iot.module.warning.ekuiperClient.WarningClient;
import cn.snowsoft.iot.module.warning.enums.api.config.vo.ConfigCountVO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class WarningServiceImpl extends ServiceImpl<WarningMapper, WarningDO> implements IWarningService {

    private static final AtomicInteger counter = new AtomicInteger(0);

    @Value("${ekuiper.url:}")
    private String url;

    @Value("${ekuiper.startSql:}")
    private String startSql;

    @Value("${ekuiper.ruleSql:}")
    private String ruleSql;

    @Value("${ekuiper.actions.server:}")
    private String actionsServer;

    @Value("${ekuiper.actions.connectionSelector:}")
    private String connectionSelector;

    @Value("${ekuiper.actions.topic:}")
    private String actionsTopic;

    @Value("${ekuiper.actions.username:}")
    private String actionsUsername;

    @Value("${ekuiper.actions.password:}")
    private String actionsPassword;

    @Value("${ekuiper.actions.sendSingle:}")
    private Boolean sendSingle;

    @Resource
    private IConfigActionService configActionService;

    @Resource
    private AdminEquipmentApi equipmentApi;


    @Override
    public IPage<WarningDO> selectWarningPage(WarningPageVO warningPageVO) {
        IPage<WarningDO> page = new Page<>(warningPageVO.getPageNo(), warningPageVO.getPageSize());
        return baseMapper.selectProductPage(page, warningPageVO);
    }


    @Override
    public CommonResult<WarningDO> saveWarningConfig(WarningSaveVO warningSaveVO) {
        if (processWarningRule(warningSaveVO)) {
            warningSaveVO.setIsEnable(0);
            if (saveOrUpdate(warningSaveVO)) {
                warningSaveVO.getActionDOList().forEach(item -> {
                    item.setId(null);
                    item.setConfigId(warningSaveVO.getId());
                });
                configActionService.updateAction(warningSaveVO);
                return CommonResult.success(warningSaveVO);
            }
            return CommonResult.error(GlobalErrorCodeConstants.LOCKED.getCode(), "保存失败");
        }
        return CommonResult.error(GlobalErrorCodeConstants.LOCKED.getCode(), "条件规则生成错误");

    }


    private boolean processWarningRule(WarningSaveVO warningSaveVO) {
        List<EquipmentDTO> equipmentDTOList = equipmentApi.getEquipmentCode(warningSaveVO.getEquipmentList());
        if (ObjectUtils.isEmpty(equipmentDTOList)) {
            return false;
        }
        Map<String, String> equipmentNameTopic = equipmentDTOList.stream().collect(Collectors.toMap(EquipmentDTO::getEquipmentCode, EquipmentDTO::getEquipmentName));

        StringBuffer sb = new StringBuffer();
        List<String> selectList = new ArrayList<>();

        warningSaveVO.getWhereList().forEach(item -> {
            sb.append(item.getWhereType());
            sb.append(computeType(item, selectList));
            sb.append(symbolType(item));
        });

        String whereSql;
        if ("1".equals(warningSaveVO.getWhereType())) {
            // 如果是普通条件
            whereSql = " WHERE (" + sb + ") AND (deviceCode = 'deviceParam')"
                    + " and cur_time() between " + "'" + warningSaveVO.getBeginTime() + "'" + " and " + "'" + warningSaveVO.getEndTime() + "'";
        } else {
            // 如果是时间窗口
            whereSql = " GROUP BY TUMBLINGWINDOW(" + warningSaveVO.getTimeType()
                    + "," + warningSaveVO.getTimeRange() + ") " + "FILTER (where deviceCode = 'deviceParam' "
                    + " and cur_time() between " + "'" + warningSaveVO.getBeginTime() + "'" + " and " + "'" + warningSaveVO.getEndTime() + "'" +")"
                    + " HAVING (" + sb + ")";
        }

        selectList.add("thetime AS thetime");

        selectList.add("equipmentParam AS deviceCode");
        selectList.add("nameParam AS deviceName");
        String ruleId;
        if (StringUtils.isNotBlank(warningSaveVO.getRuleId())) {
            ruleId = warningSaveVO.getRuleId();
        } else {
            ruleId = generateUniqueId();
        }
        selectList.add(ruleId + " ");

        String sql = startSql + " " + String.join(", ", selectList) + ruleSql + whereSql;
        JSONArray rules = new JSONArray();
        if ("0".equals(warningSaveVO.getActionProcessType())) {
            warningSaveVO.getEquipmentList().forEach(equipment -> {
                JSONObject jsonObject = new JSONObject();
                settingsMQTTAction(jsonObject);
                jsonObject.put("id", "scene-" + ruleId + "-" + equipment);
                jsonObject.put("name", "场景-" + warningSaveVO.getWarningName() + "-" + equipment);
                String equipmentCode = "'" + equipment + "'";
                String equipmentName = "'" + equipmentNameTopic.get(equipment) + "'";
                jsonObject.put("sql", sql.replace("rabbit_origin", "AttributePush_" + equipment).replace("deviceParam", equipment).replace("equipmentParam", equipmentCode).replace("nameParam", equipmentName));
                JSONObject temp1 = new JSONObject();
                temp1.put("type", "ruleCreation");
                temp1.put("data", jsonObject);
                temp1.put("id", jsonObject.getString("id"));
                rules.add(temp1);
            });
        } else {
            String converStreamSql = "CREATE STREAM streamParam () WITH (DATASOURCE=\"streamParam/result\", FORMAT=\"json\" TYPE=\"memory\");";

            String converSql;
            switch (warningSaveVO.getActionProcessType()) {
                case "1":
                    converSql = "SELECT * FROM streamParam GROUP BY COUNTWINDOW(" + warningSaveVO.getActionProcessValue()
                            + "," + warningSaveVO.getActionProcessValue() + ") HAVING COUNT(*) = " + warningSaveVO.getActionProcessValue();
                    if (warningSaveVO.getActionProcessValue() > 1) {
                        converSql = converSql.replace("SELECT *", "SELECT last_value(*, true)");
                    }
                    break;
                case "2":
                    converSql = "SELECT last_value(*, true) FROM streamParam GROUP BY SESSIONWINDOW(ss, " + warningSaveVO.getActionProcessValue() + ", 10) " + "HAVING count(*) >= " + floorDivision(warningSaveVO.getActionProcessValue(), 10) + ";";
                    break;
                default:
                    converSql = "";
                    break;
            }

            String finalConverSql = converSql;
            warningSaveVO.getEquipmentList().forEach(equipment -> {
                String streamParam = "scene_" + ruleId + "_" + equipment + "_step2";
                JSONObject converStream = new JSONObject();
                converStream.put("sql", converStreamSql.replace("streamParam", streamParam));
                JSONObject temp0 = new JSONObject();
                temp0.put("type", "streamCreation");
                temp0.put("data", converStream);
                temp0.put("id", streamParam);
                rules.add(temp0);
                JSONObject converObject = new JSONObject();
                converObject.put("id", "scene-" + ruleId + "-" + equipment + "-step2");
                converObject.put("name", "场景-" + warningSaveVO.getWarningName() + "-" + equipment + "-step2");
                converObject.put("sql", finalConverSql.replace("streamParam", streamParam));
                settingsMQTTAction(converObject);
                JSONObject temp1 = new JSONObject();
                temp1.put("type", "ruleCreation");
                temp1.put("data", converObject);
                temp1.put("id", converObject.getString("id"));
                rules.add(temp1);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("id", "scene-" + ruleId + "-" + equipment + "-step1");
                jsonObject.put("name", "场景-" + warningSaveVO.getWarningName() + "-" + equipment + "-step1");
                String equipmentCode = "'" + equipment + "'";
                String equipmentName = "'" + equipmentNameTopic.get(equipment) + "'";
                jsonObject.put("sql", sql.replace("rabbit_origin", "AttributePush_" + equipment).replace("deviceParam", equipment).replace("equipmentParam", equipmentCode).replace("nameParam", equipmentName));
                settingsMemoryAction(jsonObject, streamParam + "/result");
                JSONObject temp2 = new JSONObject();
                temp2.put("type", "ruleCreation");
                temp2.put("data", jsonObject);
                temp2.put("id", jsonObject.getString("id"));
                rules.add(temp2);
            });
        }
        warningSaveVO.setRuleId(ruleId);
        warningSaveVO.setRuleExpression(JSONArray.toJSONString(warningSaveVO.getWhereList()));
        warningSaveVO.setRuleSql(JSONArray.toJSONString(rules));
        warningSaveVO.setEquipmentCode(String.join(",", warningSaveVO.getEquipmentList()));
        return Boolean.TRUE;
    }

    @Override
    public Boolean deleteWarningConfig(Long id) {
        WarningDO warningDO = getById(id);
        if (warningDO.getIsEnable() == 1) {
            JSONArray rules = JSONObject.parseArray(warningDO.getRuleSql());
            if (ObjectUtils.isNotEmpty(rules)) {
                rules.forEach(e -> {
                    JSONObject rule = (JSONObject) e;
                    switch (rule.getString("type")) {
                        case "ruleCreation":
                            WarningClient.ruleDelete(rule.getString("id"), url);
                            break;
                        case "streamCreation":
                            WarningClient.streamDelete(rule.getString("id"), url);
                            break;
                        default:
                            break;
                    }
                });
            }
        }

        configActionService.deleteByConfigId(id);
        return removeById(id);
    }


    @SneakyThrows
    @Override
    public CommonResult<WarningDO> updateStatus(WarningDO warningDO) {
        WarningDO warning = getById(warningDO.getId());
        if (warningDO.getIsEnable() != warning.getIsEnable() ) {
            try {
                JSONArray rules = JSONObject.parseArray(warning.getRuleSql());
                if (ObjectUtils.isNotEmpty(rules)) {
                    if (warningDO.getIsEnable() == 1) {
                        List<JSONObject> ruleList = new ArrayList<>();
                        rules.forEach(e -> {
                            JSONObject rule = (JSONObject) e;
                            switch (rule.getString("type")) {
                                case "ruleCreation":
                                    ruleList.add(rule.getJSONObject("data"));
                                    break;
                                case "streamCreation":
                                    WarningClient.streamCreation(rule.getJSONObject("data"), url);
                                    break;
                                default:
                                    break;
                            }
                        });
                        ruleList.forEach(e -> {
                            WarningClient.ruleCreation(e, url);
                        });

                    } else {
                        List<String> streamList = new ArrayList<>();
                        rules.forEach(e -> {
                            JSONObject rule = (JSONObject) e;
                            switch (rule.getString("type")) {
                                case "ruleCreation":
                                    WarningClient.ruleDelete(rule.getString("id"), url);
                                    break;
                                case "streamCreation":
                                    streamList.add(rule.getString("id"));
                                    break;
                                default:
                                    break;
                            }
                        });
                        streamList.forEach(e -> {
                            WarningClient.streamDelete(e, url);
                        });
                    }
                }
            } catch (Exception e) {
                return CommonResult.error(GlobalErrorCodeConstants.LOCKED.getCode(), (warningDO.getIsEnable() == 1 ? "启用" : "停用") + "异常");
            }
            return lambdaUpdate().set(WarningDO::getIsEnable, warningDO.getIsEnable())
                    .eq(WarningDO::getId, warningDO.getId())
                    .update() ? CommonResult.success(warningDO) : CommonResult.error(GlobalErrorCodeConstants.LOCKED.getCode(), "操作失败");
        }
        return CommonResult.success(warningDO);
    }


    @Override
    public WarningDetailVO selectWarningById(Long id) {
        WarningDetailVO warningDetailVO = new WarningDetailVO();
        WarningDO warningDO = getByRuleId(id);
        BeanUtils.copyProperties(warningDO, warningDetailVO);
        List<ConfigActionDO> actionDOList = configActionService.getActionByConfigId(warningDO.getId());
        warningDetailVO.setActionDOList(actionDOList);
        return warningDetailVO;
    }

    @Override
    public WarningDetailVO selectWarningByWarningId(Long id) {
        WarningDetailVO warningDetailVO = new WarningDetailVO();
        WarningDO warningDO = baseMapper.selectById(id);
        BeanUtils.copyProperties(warningDO, warningDetailVO);
        List<ConfigActionDO> actionDOList = configActionService.getActionByConfigId(warningDO.getId());
        warningDetailVO.setActionDOList(actionDOList);
        return warningDetailVO;
    }
    @Override
    public CommonResult<WarningSaveVO> getWarningById(Long id) {
        WarningSaveVO warningSaveVO = new WarningSaveVO();
        WarningDO warningDO = getById(id);
        BeanUtils.copyProperties(warningDO, warningSaveVO);
        List<ConfigActionDO> actionDOList = configActionService.getActionByConfigId(warningDO.getId());
        warningSaveVO.setActionDOList(actionDOList);
        warningSaveVO.setWhereList(JSONObject.parseArray(warningDO.getRuleExpression(), ConfigRule.class));
        if(ObjectUtils.isNotEmpty(warningDO.getEquipmentCode())){
            warningSaveVO.setEquipmentList(Arrays.asList(warningDO.getEquipmentCode().split(",")));

        }
        return CommonResult.success(warningSaveVO);
    }

    @Override
    public CommonResult<Boolean> restart(Long id) {
        WarningDO warning = getById(id);
        if (warning.getIsEnable() == 1) {
            JSONArray rules = JSONObject.parseArray(warning.getRuleSql());
            if (ObjectUtils.isNotEmpty(rules)) {
                rules.forEach(e -> {
                    JSONObject rule = (JSONObject) e;
                    switch (rule.getString("type")) {
                        case "ruleCreation":
                            WarningClient.ruleRestart(rule.getString("id"), url);
                            break;
                        default:
                            break;
                    }
                });
            }
            return CommonResult.success(null);
        }
        return CommonResult.error(GlobalErrorCodeConstants.LOCKED.getCode(), "场景未启用，无需重启");
    }


    private void settingsMQTTAction(JSONObject jsonObject) {
        JSONArray actionsArray = new JSONArray();
        JSONObject mqttAction = new JSONObject();
        JSONObject mqttObject = new JSONObject();
        mqttObject.put("connectionSelector", connectionSelector);
        mqttObject.put("server", actionsServer);
        mqttObject.put("topic", actionsTopic);
        if (actionsUsername.isEmpty()) {
            mqttObject.put("username", "");
        } else {
            mqttObject.put("username", actionsUsername);
        }
        if (actionsPassword.isEmpty()) {
            mqttObject.put("password", "");
        } else {
            mqttObject.put("password", actionsPassword);
        }
        mqttObject.put("sendSingle", sendSingle);
        mqttAction.put("mqtt", mqttObject);
        actionsArray.add(mqttAction);
        jsonObject.put("actions", actionsArray);
    }

    private void settingsMemoryAction(JSONObject jsonObject, String topic) {
        JSONArray actionsArray = new JSONArray();
        JSONObject memoryAction = new JSONObject();
        JSONObject memoryObject = new JSONObject();
        memoryObject.put("topic", topic);
        memoryAction.put("memory", memoryObject);
        actionsArray.add(memoryAction);
        jsonObject.put("actions", actionsArray);
    }

    public static String generateUniqueId() {
        long timestamp = System.currentTimeMillis();
        int randomNumber = (int) (Math.random() * 1000);
        int uniqueId = counter.getAndIncrement();

        String id = String.format("%d%03d%04d", timestamp, randomNumber, uniqueId);

        if (id.length() > 15) {
            id = id.substring(0, 15);
        } else if (id.length() < 15) {
            id = String.format("%-15s", id).replace(' ', '0');
        }
        return id;
    }

    @Override
    public WarningDO getByRuleId(Long id) {
        return baseMapper.getByRuleId(id);
    }

    @Override
    public List<ConfigCountVO> getWarningCountByEquipmentId(List<String> equipmentCodeList) {
        List<ConfigCountVO> warningCountByEquipmentId = baseMapper.getWarningCountByEquipmentId(equipmentCodeList);
        Map<String, ConfigCountVO> stringConfigCountVOMap = warningCountByEquipmentId.stream().collect(Collectors.toMap(e -> e.getEquipmentCode(), e -> e));
        List<ConfigCountVO> configCount = new ArrayList<>();
        equipmentCodeList.stream().forEach(e -> {
            ConfigCountVO configCountVO = new ConfigCountVO();
            ConfigCountVO countVO = stringConfigCountVOMap.get(e);
            if (ObjectUtils.isNotEmpty(countVO)) {
                configCountVO.setWarningCount(countVO.getWarningCount());
                configCountVO.setEquipmentCode(e);
            } else {
                configCountVO.setWarningCount(0);
                configCountVO.setEquipmentCode(e);
            }
            configCount.add(configCountVO);
        });
        return configCount;
    }

    @Override
    public Integer getConfifCount() {
        return baseMapper.getConfifCount();
    }

    @Override
    public List<EquipmentRelateWarningVO> getEquipmentRelateWarning() {
        return baseMapper.getEquipmentRelateWarning();
    }

    @Override
    public boolean deleteByEquipmentId(Long id) {
        List<WarningDO> warningDOList = baseMapper.selectByEquipmentId(id);
        boolean status = deleteBatchConfig(warningDOList);
        return status;
    }

    @Override
    public List<WarningConfigStatusVO> getStatusCount() {
        return baseMapper.getStatusCount();
    }

    @Override
    public Boolean untie(Long id, String equipmentCode) {
        WarningDO warningDO = getById(id);
        String equipmentCodes = warningDO.getEquipmentCode();
        if (equipmentCodes.isEmpty()) {
            return false;
        }
        List<String> equipmentCodeList = Arrays.asList(equipmentCodes.split(","));
        equipmentCodeList = equipmentCodeList.stream().filter(e -> !e.equals(equipmentCode)).collect(Collectors.toList());
        warningDO.setEquipmentCode(String.join(",", equipmentCodeList));
        String s = untieDeleteRule(warningDO, equipmentCode);
        warningDO.setRuleSql(s);

        return saveOrUpdate(warningDO);
    }

    @Override
    public CommonResult<Boolean> equipmentUntie(String equipmentCode) {
        // 根据设备编码查询场景数据
        List<WarningDO> warningDOList = baseMapper.getWarningByEquipmentCode(equipmentCode);
        for (WarningDO warningDO : warningDOList) {
            String equipmentCodes = warningDO.getEquipmentCode();
            if (equipmentCodes.isEmpty()) {
                return CommonResult.success(false);
            }
            List<String> equipmentCodeList = Arrays.asList(equipmentCodes.split(","));
            // 移除当前设备（后续需要将告警平台关于此设备的配置数据同步解绑更新，这里只是完成了系统平台的业务操作；）
            //如果该场景启用  则删除当前设备的规则  并且需要将ruleSql中关于此设备的数据删除
            equipmentCodeList = equipmentCodeList.stream().filter(e -> !e.equals(equipmentCode)).collect(Collectors.toList());
            warningDO.setEquipmentCode(String.join(",", equipmentCodeList));
            String s = untieDeleteRule(warningDO, equipmentCode);
            warningDO.setRuleSql(s);
        }
        saveOrUpdateBatch(warningDOList);
        return CommonResult.success(true);
    }

    public String untieDeleteRule(WarningDO warningDO, String equipmentCode){
        String ruleKey = "scene-" + warningDO.getRuleId() + "-" + equipmentCode;
        JSONArray rules = JSONObject.parseArray(warningDO.getRuleSql());
        List<String> ruleKeyStreams = new ArrayList<>();
        if (ObjectUtils.isNotEmpty(rules)) {
            for (int i = 0; i < rules.size(); i++) {
                JSONObject rule = (JSONObject) rules.get(i);
                if ("ruleCreation".equals(rule.getString("type")) && rule.getString("id").contains(ruleKey)){
                    if (warningDO.getIsEnable() == 1){
                        WarningClient.ruleDelete(rule.getString("id"), url);
                    }
                    rules.remove(i);
                    i--;
                }
                if ("streamCreation".equals(rule.getString("type")) && rule.getString("id").contains(ruleKey.replace("-","_"))){
                    if (warningDO.getIsEnable() == 1){
                        ruleKeyStreams.add(rule.getString("id"));
                    }
                    rules.remove(i);
                    i--;
                }
            }
            ruleKeyStreams.stream().forEach(rule ->{
                WarningClient.streamDelete(rule, url);
            });
        }
        return rules.toJSONString();
    }

    public boolean deleteBatchConfig(List<WarningDO> warning) {
        WarningClient warningClient = new WarningClient();
        boolean isSuccess = false;
        boolean status = true;
        for (WarningDO warningDO : warning) {
            isSuccess = warningClient.ruleDelete(warningDO.getRuleId(), url);
            if (isSuccess) {
                removeById(warningDO.getId());
                configActionService.deleteByConfigId(warningDO.getId());
                status = true;
            } else {
                status = false;
            }
        }
        return status;
    }

    public String symbolType(ConfigRule configRule) {
        if(ObjectUtils.isEmpty(configRule.getConditionType())){
            return "";
        }
        switch (configRule.getConditionType()) {
            case "1":
                return "= " + configRule.getParam1() + " ";
            case "2":
                return "!= " + configRule.getParam1() + " ";
            case "3":
                return "> " + configRule.getParam1() + " ";
            case "4":
                return ">= " + configRule.getParam1() + " ";
            case "5":
                return "< " + configRule.getParam1() + " ";
            case "6":
                return "<= " + configRule.getParam1() + " ";
            case "7":
                return "BETWEEN " + configRule.getParam1() + " AND " + configRule.getParam2() + " ";
            case "8":
                return "NOT BETWEEN " + configRule.getParam1() + " AND " + configRule.getParam2() + " ";
            case "9":
                return "IN (" + configRule.getParam1() + ") ";
            case "10":
                return "NOT IN (" + configRule.getParam1() + ") ";
            default:
                return "";
        }
    }


    public String computeType(ConfigRule configRule, List<String> selectList) {
        switch (configRule.getValueType()) {
            case "1":
                selectList.add(configRule.getPointCode() + " AS " + configRule.getPointCode());
                return " " + configRule.getPointCode() + " ";
            case "2":
                selectList.add(" lag(" + configRule.getPointCode() + ") AS lag_" + configRule.getPointCode());
                return " lag(" + configRule.getPointCode() + ") " + "OVER (PARTITION BY deviceCode = 'deviceParam') ";
            case "3":
                selectList.add(" avg(" + configRule.getPointCode() + ") AS avg_" + configRule.getPointCode());
                return " avg(" + configRule.getPointCode() + ") ";
            case "4":
                selectList.add(" max(" + configRule.getPointCode() + ") AS max_" + configRule.getPointCode());
                return " max(" + configRule.getPointCode() + ") ";
            case "5":
                selectList.add(" min(" + configRule.getPointCode() + ") AS min_" + configRule.getPointCode());
                return " min(" + configRule.getPointCode() + ") ";
            case "6":
                selectList.add(" sum(" + configRule.getPointCode() + ") AS sum_" + configRule.getPointCode());
                return " sum(" + configRule.getPointCode() + ") ";
            case "7":
                selectList.add(" count(" + configRule.getPointCode() + ") AS count_" + configRule.getPointCode());
                return " count(" + configRule.getPointCode() + ") ";
            default:
                return "";
        }
    }


    public static double floorDivision(double numerator, double denominator) {
        if (denominator == 0) {
            throw new ArithmeticException("分母不可为零");
        }
        return Math.floor(numerator / denominator);
    }
}
